#include <windows.h>

#include <process.h>
#include <stdio.h>

#include "r250.h"
#include "rndlcg.h"

//
// tests thread-safeness of R250
//

#define NUMTHREADS	64		// max 64

HANDLE hgo, hdone[NUMTHREADS];
unsigned long result[NUMTHREADS];

unsigned __stdcall tproc(DWORD);

void main()
{
	long i;
	HANDLE th;
	DWORD id;

	hgo = CreateEvent(NULL, TRUE, FALSE, NULL);

	for (i = 0; i < NUMTHREADS; i++)
	{
		hdone[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
		th = (HANDLE)_beginthreadex(NULL, 0, (unsigned(__stdcall*)(void*))tproc,
			(void*)i, 0, (unsigned*)&id);
		CloseHandle(th);
	}

	SetEvent(hgo);

	if (WAIT_FAILED==WaitForMultipleObjects(NUMTHREADS, hdone, TRUE, INFINITE))
	{
		printf("Wait failed (%08x)\n", GetLastError());
		return;
	}

	CloseHandle(hgo);

	printf("Thread     R250  \n");
	for (i = 0; i < NUMTHREADS; i++)
	{
		CloseHandle(hdone[i]);
		printf("%6d   %08x\n", i, result[i]);
	}
}

unsigned __stdcall tproc(DWORD which)
{
	R250* r250;
	int i;

	WaitForSingleObject(hgo, INFINITE);

	r250 = new R250(12345 + which);

	for (i = 0; i < 10000; i++)
		result[which] = r250->rani();

	SetEvent(hdone[which]);

	_endthreadex(0);
	return 0;
}
